package demo01;

import java.util.HashMap;
import java.util.Map;

/*
 *  java.util.Map<k,v>集合
 *  Map集合的特点：
 *      1. Map集合是一个双列集合，一个元素包含两个值（一个key，一个value）
 *      2. Map集合中的元素，key和value的数据类型可以相同，也可以不同
 *      3. Map集合中的元素，key是不允许重复的，value是可以重复的
 *      4. Map集合中的元素，key和value是一一对应的
 * 
 *  java.util.HashMap<k,v>集合 implements Map<k,v>接口
 *  HashMap集合的特点：
 *      1. HashMap集合底层是哈希表，查询的速度非常快
 *          JDK1.8前：数组+单向链表
 *          JDK1.8后：数组+单向链表/红黑树（链表的长度超过8），提高了查询的速度
 *      2. HashMap集合是一个无序的集合，存储元素和取出元素的顺序有可能不一致
 * 
 *  java.util.LinkedHashMap<k,v>集合 extends HashMap<k,v>集合
 *  LinkedHadhMap集合的特点：
 *      1. LinkedHashMap集合底层是哈希表+链表的结构（保证了迭代的顺序） 
 *      2. LinkedHashMap集合是一个有序的集合，存储元素和取出元素的顺序是一致的
 */
public class Demo01Map {
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<>(); // 使用多态创建Map集合对象
        demo01(map);
        demo02(map);
        demo03(map);
        demo04(map);
    }

    /*
     *  boolean containsKey(Object key)：判断集合中是否包含指定的键
     *  包含则返回true，不包含则返回false
     */
    private static void demo04(Map<String, Integer> map) {
        System.out.println("b1：" + map.containsKey("土司鸡")); // true，集合中包含键"土司鸡"
        System.out.println("b2：" + map.containsKey("哈利")); // false，集合中不包含键"哈利"
    }

    /*
     *  public V get(Object key)：根据指定的键，在Map集合中获取对应的值
     *  返回值：V
     *      key如果存在，V返回对应的value值
     *      key如果不存在，V返回null
     */
    private static void demo03(Map<String, Integer> map) {
        System.out.println("v1：" + map.get("土司鸡")); // 19，该键在集合中存在，返回对应的值
        System.out.println("v2：" + map.get("哈利")); // null，该键在集合中不存在
        
        /*
         *  注意：
         *      由于romove/put/get方法有可能返回null，所以需要接收它们的返回值时，尽量使用引用类型（包装类）接收
         *      不要用基本类型自动拆箱规则接收，否则可能报出空指针异常
         */
        // int Integer = map.get("哈利"); // NullPointerException空指针异常，返回了null，而接收对象是基本类型，无法接收null，因此报错
        Integer integer = map.get("哈利");
        System.out.println("v3：" + integer); // null
    }

    /*
     *  public V remove(Object key)：把指定的键 所对应的键值对元素 在Map集合中删除，返回被删除元素的值
     *  返回值：V
     *      key如果存在，V返回被删除的值
     *      key如果不存在，V返回null
     */
    private static void demo02(Map<String, Integer> map) {
        Integer integer = map.remove("粹花");
        System.out.println("v1：" + integer); // 1，该键在集合中存在，返回被删除的键值对的值

        Integer integer2 = map.remove("哈利");
        System.out.println("v2：" + integer2); // null，该键在集合中不存在
        System.out.println(map); // {提莫=22, 土司鸡=19, 老虎=20}
    }

    /*
     *  public V put(K key, V value)：把指定的键与指定的值添加到Map集合中
     *  返回值：V
     *      存储键值对时，key不重复，V返回null
     *      存储键值对时，key重复，会使用新的value替换map中重复key的value值，V返回被替换的value值
     */
    private static void demo01(Map<String, Integer> map) {
        Integer string = map.put("土司鸡", 18);
        System.out.println("v1：" + string); // null，key是新的key，置入后返回null
        
        Integer string2 = map.put("土司鸡", 19);
        System.out.println("v2：" + string2); // 18，key已存在，置入后替换新的value值，并返回原来对应的value值
        System.out.println(map); // {土司鸡=19}

        map.put("老虎", 20); // 一般情况下放入新键值对不需要使用put的返回值
        map.put("提莫", 22);
        map.put("粹花", 1);
        System.out.println(map); // {提莫=22, 粹花=1, 土司鸡=19, 老虎=20}，结果是无序的
    }
}